package api

import (
	"strconv"

	"gitee.com/war2001/NiuMaEasyGo/model"
	"gitee.com/war2001/NiuMaEasyGo/nm_core/middleware"
	"gitee.com/war2001/NiuMaEasyGo/nm_core/router"
	"gitee.com/war2001/NiuMaEasyGo/service"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"golang.org/x/crypto/bcrypt"
)

// UserController 用户控制器
type UserController struct {
	userService       *service.UserService
	permissionService *service.PermissionService
}

// NewUserController 创建用户控制器
func NewUserController(userService model.UserService, permissionService *service.PermissionService) *UserController {
	return &UserController{
		userService:       userService.(*service.UserService),
		permissionService: permissionService,
	}
}

// SystemDirectoryMetadata 系统管理目录元数据
func (c *UserController) SystemDirectoryMetadata() router.RouteMetadata {
	return router.RouteMetadata{
		Title:        "系统管理",
		Path:         "/system",
		Component:    "LAYOUT",
		Icon:         "setting",
		Permission:   "",
		ParentPath:   "",
		MenuType:     "directory",
		MenuCategory: "system",
		Method:       "",
		APIPath:      "",
		RequireAuth:  true,
		OrderNum:     100,
	}
}

// ListMetadata 获取用户列表元数据
func (c *UserController) ListMetadata() router.RouteMetadata {
	return router.RouteMetadata{
		Title:        "用户列表",
		Path:         "/system/user",
		Component:    "/system/user/index",
		Icon:         "user",
		Permission:   "system:user:list",
		ParentPath:   "/system",
		MenuType:     "menu",
		MenuCategory: "system",
		Method:       "GET",
		APIPath:      "/user/list",
		RequireAuth:  true,
		OrderNum:     1,
	}
}

// List 获取用户列表
func (c *UserController) List(ctx *gin.Context) {
	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))

	// 获取查询参数
	username := ctx.Query("username")
	status := ctx.Query("status")

	// 从上下文中获取用户ID和租户ID
	userID, _ := ctx.Get("user_id")
	tenantID, _ := ctx.Get("tenant_id")

	// 获取用户角色
	var roleIDs []uint64
	var isSysAdmin bool

	// 检查是否是系统管理员
	if userID != nil {
		// 使用权限服务获取角色
		var roles []model.SysRole
		if c.permissionService != nil {
			roles, _ = c.permissionService.GetUserRoles(uint64(userID.(uint)))
		}

		for _, role := range roles {
			roleIDs = append(roleIDs, uint64(role.ID))
			if role.Code == "admin" {
				isSysAdmin = true
			}
		}
	}

	// 构建查询条件
	condition := make(map[string]interface{})
	if username != "" {
		condition["username LIKE ?"] = "%" + username + "%"
	}
	if status != "" {
		condition["status"] = status
	}

	// 应用数据权限过滤
	var users []model.User
	var total int64

	// 获取数据库连接
	db := c.permissionService.DB
	query := db.Model(&model.User{})

	// 应用数据权限
	if !isSysAdmin {
		if tenantID != nil {
			query = query.Where("tenant_id = ?", tenantID)
		}
	}

	// 应用查询条件
	for k, v := range condition {
		query = query.Where(k, v)
	}

	// 统计总数
	query.Count(&total)

	// 分页查询
	query.Offset((page - 1) * pageSize).Limit(pageSize).Find(&users)

	// 返回结果
	middleware.ResponseSuccess(ctx, gin.H{
		"list":  users,
		"total": total,
		"page":  page,
		"size":  pageSize,
	})
}

// GetMetadata 获取用户详情元数据
func (c *UserController) GetMetadata() router.RouteMetadata {
	return router.RouteMetadata{
		Title:        "用户详情",
		Path:         "/system/user/detail",
		Component:    "/system/user/detail",
		Icon:         "",
		Permission:   "system:user:query",
		ParentPath:   "/system/user",
		MenuType:     "menu",
		MenuCategory: "system",
		Method:       "GET",
		APIPath:      "/user/:id",
		RequireAuth:  true,
		Hidden:       true,
		OrderNum:     1,
	}
}

// Get 获取用户详情
func (c *UserController) Get(ctx *gin.Context) {
	id := ctx.Param("id")
	idUint, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		middleware.ResponseBadRequest(ctx, "无效的用户ID")
		return
	}

	// 从上下文中获取用户ID和租户ID
	userID, _ := ctx.Get("user_id")
	tenantID, _ := ctx.Get("tenant_id")

	// 检查权限
	if userID != nil && id != strconv.FormatUint(uint64(userID.(uint)), 10) {
		// 如果不是查询自己，需要有权限
		var tenantIDUint64 uint64
		if tenantID != nil {
			tenantIDUint64 = uint64(tenantID.(uint))
		}
		if !c.permissionService.CheckPermission(uint64(userID.(uint)), tenantIDUint64, "system:user:query") {
			middleware.ResponseForbidden(ctx, "无权限查看其他用户信息")
			return
		}
	}

	// 查询用户
	user, err := c.userService.GetByID(uint(idUint))
	if err != nil {
		middleware.ResponseNotFound(ctx, "用户不存在")
		return
	}

	// 检查租户权限
	if tenantID != nil && user.TenantID != "" && user.TenantID != tenantID.(string) {
		middleware.ResponseForbidden(ctx, "无权限查看其他租户用户信息")
		return
	}

	// 清除敏感信息
	user.Password = ""

	// 返回结果
	middleware.ResponseSuccess(ctx, user)
}

// CreateMetadata 创建用户元数据
func (c *UserController) CreateMetadata() router.RouteMetadata {
	return router.RouteMetadata{
		Title:        "创建用户",
		Path:         "",
		Component:    "",
		Icon:         "",
		Permission:   "system:user:add",
		ParentPath:   "/system/user",
		MenuType:     "button",
		MenuCategory: "system",
		Method:       "POST",
		APIPath:      "/user",
		RequireAuth:  true,
		OrderNum:     1,
	}
}

// Create 创建用户
func (c *UserController) Create(ctx *gin.Context) {
	var user model.User
	if err := ctx.ShouldBindJSON(&user); err != nil {
		middleware.ResponseBadRequest(ctx, "无效的请求参数")
		return
	}

	// 从上下文中获取租户ID
	tenantID, exists := ctx.Get("tenant_id")
	if exists && tenantID != nil {
		user.TenantID = tenantID.(string)
	}

	// 加密密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		zap.L().Error("密码加密失败", zap.Error(err))
		middleware.ResponseInternalError(ctx, "创建用户失败")
		return
	}
	user.Password = string(hashedPassword)

	// 创建用户
	if err := c.userService.Create(&user); err != nil {
		middleware.ResponseInternalError(ctx, "创建用户失败: "+err.Error())
		return
	}

	// 返回结果
	middleware.ResponseSuccess(ctx, gin.H{
		"message": "创建用户成功",
		"id":      user.ID,
	})
}

// UpdateMetadata 更新用户元数据
func (c *UserController) UpdateMetadata() router.RouteMetadata {
	return router.RouteMetadata{
		Title:        "更新用户",
		Path:         "",
		Component:    "",
		Icon:         "",
		Permission:   "system:user:edit",
		ParentPath:   "/system/user",
		MenuType:     "button",
		MenuCategory: "system",
		Method:       "PUT",
		APIPath:      "/user/:id",
		RequireAuth:  true,
		OrderNum:     2,
	}
}

// Update 更新用户
func (c *UserController) Update(ctx *gin.Context) {
	id := ctx.Param("id")
	idUint, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		middleware.ResponseBadRequest(ctx, "无效的用户ID")
		return
	}

	var user model.User
	if err := ctx.ShouldBindJSON(&user); err != nil {
		middleware.ResponseBadRequest(ctx, "无效的请求参数")
		return
	}

	// 查询原有用户
	oldUser, err := c.userService.GetByID(uint(idUint))
	if err != nil {
		middleware.ResponseNotFound(ctx, "用户不存在")
		return
	}

	// 从上下文中获取租户ID
	tenantID, exists := ctx.Get("tenant_id")
	if exists && tenantID != nil {
		// 检查租户权限
		if oldUser.TenantID != "" && oldUser.TenantID != tenantID.(string) {
			middleware.ResponseForbidden(ctx, "无权限修改其他租户用户信息")
			return
		}
	}

	// 如果修改了密码，需要加密
	if user.Password != "" && user.Password != oldUser.Password {
		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
		if err != nil {
			zap.L().Error("密码加密失败", zap.Error(err))
			middleware.ResponseInternalError(ctx, "更新用户失败")
			return
		}
		user.Password = string(hashedPassword)
	} else {
		user.Password = oldUser.Password
	}

	// 更新用户
	if err := c.userService.Update(&user); err != nil {
		middleware.ResponseInternalError(ctx, "更新用户失败: "+err.Error())
		return
	}

	// 返回结果
	middleware.ResponseSuccess(ctx, gin.H{
		"message": "更新用户成功",
	})
}

// DeleteMetadata 删除用户元数据
func (c *UserController) DeleteMetadata() router.RouteMetadata {
	return router.RouteMetadata{
		Title:        "删除用户",
		Path:         "",
		Component:    "",
		Icon:         "",
		Permission:   "system:user:delete",
		ParentPath:   "/system/user",
		MenuType:     "button",
		MenuCategory: "system",
		Method:       "DELETE",
		APIPath:      "/user/:id",
		RequireAuth:  true,
		OrderNum:     3,
	}
}

// Delete 删除用户
func (c *UserController) Delete(ctx *gin.Context) {
	id := ctx.Param("id")
	idUint, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		middleware.ResponseBadRequest(ctx, "无效的用户ID")
		return
	}

	// 查询用户
	user, err := c.userService.GetByID(uint(idUint))
	if err != nil {
		middleware.ResponseNotFound(ctx, "用户不存在")
		return
	}

	// 从上下文中获取租户ID
	tenantID, exists := ctx.Get("tenant_id")
	if exists && tenantID != nil {
		// 检查租户权限
		if user.TenantID != "" && user.TenantID != tenantID.(string) {
			middleware.ResponseForbidden(ctx, "无权限删除其他租户用户")
			return
		}
	}

	// 删除用户
	if err := c.userService.Delete(uint(idUint)); err != nil {
		middleware.ResponseInternalError(ctx, "删除用户失败: "+err.Error())
		return
	}

	// 返回结果
	middleware.ResponseSuccess(ctx, gin.H{
		"message": "删除用户成功",
	})
}

// ResetPasswordMetadata 重置密码元数据
func (c *UserController) ResetPasswordMetadata() router.RouteMetadata {
	return router.RouteMetadata{
		Title:        "重置密码",
		Path:         "",
		Component:    "",
		Icon:         "",
		Permission:   "system:user:reset",
		ParentPath:   "/system/user",
		MenuType:     "button",
		MenuCategory: "system",
		Method:       "POST",
		APIPath:      "/user/:id/reset-password",
		RequireAuth:  true,
		OrderNum:     4,
	}
}

// ResetPassword 重置密码
func (c *UserController) ResetPassword(ctx *gin.Context) {
	id := ctx.Param("id")
	idUint, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		middleware.ResponseBadRequest(ctx, "无效的用户ID")
		return
	}

	var req struct {
		Password string `json:"password" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		middleware.ResponseBadRequest(ctx, "无效的请求参数")
		return
	}

	// 查询用户
	user, err := c.userService.GetByID(uint(idUint))
	if err != nil {
		middleware.ResponseNotFound(ctx, "用户不存在")
		return
	}

	// 从上下文中获取租户ID
	tenantID, exists := ctx.Get("tenant_id")
	if exists && tenantID != nil {
		// 检查租户权限
		if user.TenantID != "" && user.TenantID != tenantID.(string) {
			middleware.ResponseForbidden(ctx, "无权限重置其他租户用户密码")
			return
		}
	}

	// 重置密码
	if err := c.userService.ResetPassword(uint(idUint), req.Password); err != nil {
		middleware.ResponseInternalError(ctx, "重置密码失败: "+err.Error())
		return
	}

	// 返回结果
	middleware.ResponseSuccess(ctx, gin.H{
		"message": "重置密码成功",
	})
}
